// Copyright (c) 2017, Xiaomi, Inc.  All rights reserved.
// This source code is licensed under the Apache License Version 2.0, which
// can be found in the LICENSE file in the root directory of this source tree.

package com.xiaomi.infra.pegasus.client;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author qinzuoyan
 *
 * This class provides interfaces to create an instance of {@link PegasusClientInterface}.
 */
public class PegasusClientFactory {
    private static final Logger LOGGER = LoggerFactory.getLogger(PegasusClientFactory.class);

    private static volatile PegasusClient singletonClient = null;
    private static String singletonClientConfigPath = null;
    private static Object singletonClientLock = new Object();

    // Create a client instance.
    // After used, should call client.close() to release resource.
    public static PegasusClientInterface createClient(String configPath) throws PException {
        return new PegasusClient(configPath);
    }

    // Get the singleton client instance with default config path of "resource:///pegasus.properties".
    public static PegasusClientInterface getSingletonClient() throws PException {
        return getSingletonClient("resource:///pegasus.properties");
    }

    // Get the singleton client instance.
    // After used, should call PegasusClientFactory.closeSingletonClient() to release resource.
    //
    // configPath could be:
    // - zookeeper path  : zk://host1:port1,host2:port2,host3:port3/path/to/config
    // - local file path : file:///path/to/config
    // - java resource   : resource:///path/to/config
    public static PegasusClientInterface getSingletonClient(String configPath) throws PException {
        synchronized (singletonClientLock) {
            if (singletonClient == null) {
                try {
                    singletonClient = new PegasusClient(configPath);
                    singletonClientConfigPath = configPath;
                    LOGGER.info("Create Singleton PegasusClient with config path \"" + configPath + "\"");
                } catch (Throwable e) {
                    throw new PException("Create Singleton PegasusClient Failed", e);
                }
            }
            else if (!singletonClientConfigPath.equals(configPath)){
                LOGGER.error("Singleton PegasusClient Config Path Conflict: \""
                        + configPath + "\" VS \"" + singletonClientConfigPath + "\"");
                throw new PException("Singleton PegasusClient Config Path Conflict");
            }
            return singletonClient;
        }
    }

    // Close the singleton client instance.
    public static void closeSingletonClient() throws PException {
        synchronized (singletonClientLock) {
            if (singletonClient != null) {
                LOGGER.info("Close Singleton PegasusClient with config path \"" + singletonClientConfigPath + "\"");
                singletonClient.close();
                singletonClient = null;
                singletonClientConfigPath = null;
            }
        }
    }
}
